home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 014 / amiga3d / subdisplay.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  11KB  |  470 lines

  1. #include <exec/types.h>
  2. #include <exec/nodes.h>
  3. #include <exec/lists.h>
  4. #include <exec/memory.h>
  5. #include <hardware/blit.h>
  6. #include <hardware/custom.h>
  7. #include <graphics/gfx.h>
  8. #include <graphics/clip.h>
  9. #include <graphics/rastport.h>
  10. #include <graphics/view.h>
  11. #include <graphics/text.h>
  12. #include <graphics/gfxmacros.h>
  13.  
  14. #include <graphics/layers.h>
  15. #include <intuition/intuition.h>
  16. #include <libraries/dos.h>
  17. #include "threed.h"
  18.  
  19. #define FIXEDILLUMINATION
  20.  
  21. extern UBYTE title[] ;
  22.  
  23. extern struct Custom custom;
  24.  
  25. extern struct TmpRas tmpras;
  26.  
  27. extern struct BitMap bitmap0;
  28. extern struct BitMap bitmap1;
  29.  
  30. extern struct RastPort r[2];
  31. extern struct RastPort *rp[2];
  32.  
  33. extern struct RasInfo ri[2];
  34. extern struct RasInfo *rip[2];
  35.  
  36. extern struct RasInfo *irip;
  37.  
  38. extern WORD pcount ;
  39. extern WORD vcount ;
  40.  
  41. extern UWORD frametoggle ;
  42.  
  43. extern BPTR objectsegment ;
  44.  
  45. extern struct Object *Amiga ;
  46.  
  47. extern long GfxBase;
  48. extern long DosBase;
  49.  
  50. extern int (*subroutines[])();
  51.  
  52. /******************************************************************************/
  53.  
  54. subdisplayuniverse(view,screen,window,cameraobjectinfo,objectinfo,subobjectinfo)
  55. struct View *view;
  56. struct Screen *screen;
  57. struct Window *window;
  58. struct Objectinfo *cameraobjectinfo;
  59. struct Objectinfo *objectinfo;
  60. struct Objectinfo *subobjectinfo;
  61. {
  62.     int argc = 0;
  63.     char *argv[MAXNUMARGS];
  64.     struct Objectinfo *thisobjectinfo; 
  65.  
  66. /* set up parameter passing information for this display */
  67.  
  68.     argv[0] = &thisobjectinfo;
  69.     argv[1] = subroutines;
  70.  
  71.     argc = 2;
  72.  
  73. /* PROCESS ALL THE OBJECTS IN THE LIST POINTED TO BY OBJECTINFO */
  74.  
  75.     thisobjectinfo = subobjectinfo;
  76.  
  77.     while(thisobjectinfo)
  78.     {
  79.    int thisobjecterror = FALSE;
  80.  
  81.    /* process this object */
  82.  
  83.    if(thisobjectinfo->objectprocedure)
  84.    {
  85.        int (*function)();
  86.  
  87.        /* call the object's procedure */
  88.  
  89. #ifdef ODEBUG
  90.        printf("do3d: object(%lx) procedure = %lx\n",
  91.           thisobjectinfo,thisobjectinfo->objectprocedure);
  92. #endif
  93.        function = thisobjectinfo->objectprocedure;
  94.        thisobjecterror = (*function)(argc,argv);
  95.  
  96.    }
  97.  
  98.    /* concatenate this submatrix with the next higher level display matrix */
  99.  
  100.         {
  101.        struct UV uv;
  102.  
  103.        uv = *thisobjectinfo->objectmatrix;
  104.  
  105.        transpose(&uv);
  106.  
  107.        cat(thisobjectinfo->displaymatrix,&uv,objectinfo->displaymatrix);
  108.  
  109.        transpose(thisobjectinfo->displaymatrix);
  110.  
  111.    }
  112.  
  113.       
  114.    /* convert this object's position to the next higher lever display frame-of-reference */
  115.  
  116.    matrix(thisobjectinfo->displayposition,thisobjectinfo->objectposition,
  117.       objectinfo->displaymatrix);
  118.  
  119.    /* then determine this subobjects's universal reference position */
  120.    
  121.    addvect(thisobjectinfo->displayposition,objectinfo->displayposition,
  122.       thisobjectinfo->displayposition);
  123.  
  124.    /* process any subobjects dependent on this object before displaying it */
  125.  
  126.    {
  127.        struct Objectinfo *nextsubobjectinfo;
  128.  
  129.        nextsubobjectinfo = thisobjectinfo->subobjectinfo;
  130.  
  131.        while(nextsubobjectinfo)
  132.        {
  133.       /* subdisplay each next subobject */
  134.  
  135.       subdisplayuniverse(view,screen,window,cameraobjectinfo,thisobjectinfo,nextsubobjectinfo);
  136.  
  137.       nextsubobjectinfo = nextsubobjectinfo->nextobjectinfo;
  138.  
  139.        }
  140.  
  141.    }
  142.  
  143.    {
  144.        
  145.        struct Coordinate centerpoint;
  146.  
  147.        /* concatenate this object's matrix with the camera matrix for display through camera viewpoint */
  148.  
  149.        {
  150.       struct UV uv1, uv2;
  151.  
  152.       subvect(cameraobjectinfo->objectposition,thisobjectinfo->displayposition,¢erpoint);
  153.  
  154.       uv1 = *thisobjectinfo->displaymatrix;
  155.  
  156.       uv2 = *cameraobjectinfo->objectmatrix;
  157.  
  158.       transpose(&uv1);
  159.  
  160.       /*transpose(&uv2);*/
  161.  
  162.       cat(thisobjectinfo->displaymatrix,&uv2,&uv1);
  163.  
  164.       /*transpose(thisobjectinfo->displaymatrix);*/
  165.       
  166.       matrix(¢erpoint,¢erpoint,cameraobjectinfo->objectmatrix);
  167.  
  168.  
  169.        }
  170.        
  171.        if ( (centerpoint.z > 0)
  172.           &&
  173.           (( (centerpoint.z) - ( (centerpoint.x < 0) ? -centerpoint.x : centerpoint.x )) > 0)
  174.           &&
  175.           (( (centerpoint.z) - ( (centerpoint.y < 0) ? -centerpoint.y : centerpoint.y )) > 0) )
  176.        {
  177.  
  178.  
  179.       /* rotate the 3d normals*/
  180.  
  181. #ifdef DEBUG
  182.       printf("do3d: rotate the 3d normals\n");
  183. #endif
  184.  
  185.       rotate(thisobjectinfo->displaymatrix,thisobjectinfo->objectnumnormals,
  186.          thisobjectinfo->objectnormals,thisobjectinfo->objectbufnormals);
  187.  
  188.       /* rotate, translate, and perspect the 3d points */
  189.  
  190.       dopoints(thisobjectinfo->displaymatrix,¢erpoint,
  191.          thisobjectinfo->objectnumpoints,thisobjectinfo->objectpoints,
  192.          thisobjectinfo->objectbufpoints);
  193.  
  194.        }
  195.        else
  196.        {
  197.       
  198.       /* this object out of 45 degree frustrum */
  199.  
  200.            thisobjectinfo = thisobjectinfo->nextobjectinfo;
  201.  
  202.            /* so process the next object */
  203.  
  204.            continue;
  205.        }
  206.  
  207.    }
  208.  
  209.     /* draw the polygons by traversing the polygon list */
  210.  
  211.     {
  212.    WORD polycount = 0;
  213.    WORD *nextcolor;
  214.    struct Coordinate **nextn;
  215.    struct Coordinate **nextp;
  216.    struct Coordinate *lastn = 0;
  217.    WORD endflag = FALSE;
  218.  
  219.    /* intialize buffer pointers */
  220.  
  221.    nextcolor = thisobjectinfo->colorbuf;
  222.    nextn = thisobjectinfo->nptrbuf;
  223.    nextp = thisobjectinfo->pptrbuf;
  224.  
  225.    for(polycount = 0; polycount < thisobjectinfo->objectnumpolys; polycount++)
  226.    {
  227.        struct Polygon **np;
  228.        WORD vc;
  229.        struct Coordinate **v;
  230.        struct Coordinate *n;
  231.        struct Coordinate *c0;
  232.        struct Coordinate *c1;
  233.        struct Coordinate *c2;
  234.        WORD bright;
  235.        WORD firstx, firsty;
  236.  
  237. #ifdef DEBUG
  238.        printf("poly %lx: \n",polycount);
  239. #endif
  240.        np = (thisobjectinfo->objectpolys+polycount);
  241.  
  242. #ifdef DEBUG
  243.        printf("np = %lx\n",np);
  244. #endif
  245.  
  246. #ifdef DEBUG
  247.        printf("vertexcount = %lx\n",(*np)->vertexcount);
  248. #endif
  249.  
  250. #ifdef DRAWDEBUG
  251.        printf("poly %lx: color = %lx\n",polycount,*nextcolor);
  252. #endif
  253.  
  254.        /* backface removal */
  255.  
  256.        /* first, simple clip */
  257.        if (((*nextn)->z) > 0) 
  258.        {
  259.       nextcolor++;
  260.       nextn++;
  261.       nextp = (nextp+((*np)->vertexcount));
  262.       continue;
  263.        }
  264.        
  265.        /* now, test z component of dynamically computed polygon normal */
  266.        
  267.        c0 = (struct Coordinate *)(*(nextp));
  268.        c1 = (struct Coordinate *)(*(nextp+1));
  269.        c2 = (struct Coordinate *)(*(nextp+2));
  270.  
  271.        /* if polygon's normal faces away from the screen, or is perpendicular, ignore it */
  272.  
  273. #ifdef DRAWDEBUG
  274.        printf("c0->x = %lx c0->y = %lx\n",c0->x,c0->y); 
  275.        printf("c1->x = %lx c1->y = %lx\n",c1->x,c1->y); 
  276.        printf("c2->x = %lx c2->y = %lx\n",c2->x,c2->y); 
  277. #endif
  278.  
  279.        /* fine clipping */
  280.  
  281.        if (((smuls(((c1->x)-(c0->x)),((c2->y)-(c1->y))))-(smuls(((c2->x)-(c1->x)),((c1->y)-(c0->y))))) >= 0)
  282.        {
  283.       nextcolor++;
  284.       nextn++;
  285.       nextp = (nextp+((*np)->vertexcount));
  286.       continue;
  287.        }
  288.  
  289.        /* illumination */
  290.  
  291. #ifndef FIXEDILLUMINATION
  292.  
  293.        bright = (((-(((*nextn)->x+(*nextn)->y))>>1)+(0x4000))>>11);
  294. #else
  295.  
  296.        bright = (WORD)*nextcolor;
  297. #endif
  298.        /* ceiling */
  299.  
  300.        bright = (bright > 0xF)?0xF:bright;
  301.  
  302. #ifdef DRAWDEBUG
  303.        printf("poly %lx: bright = %lx\n",polycount,bright);
  304. #endif
  305.  
  306.             for(vc = 0; vc < (*np)->vertexcount; vc++)
  307.        {
  308.       WORD x,y;
  309. #ifdef DRAWDEBUG
  310.       printf("vertex %lx : (thisobjectinfo->objectbufpoints+poff) = %lx\n",vc,*nextp);
  311. #endif
  312.  
  313. #ifdef DRAWDEBUG
  314.       printf("(thisobjectinfo->objectbufpoints+poff)->x = %lx\n",(*nextp)->x);
  315.       printf("(thisobjectinfo->objectbufpoints+poff)->y = %lx\n",(*nextp)->y);
  316.       printf("(thisobjectinfo->objectbufpoints+poff)->z = %lx\n",(*nextp)->z);
  317. #endif
  318.  
  319.       /* draw stuff in */
  320.  
  321. #ifdef DRAWDEBUG
  322.       printf("SetAPen = bright\n");
  323. #endif
  324.       SetAPen(rp[frametoggle ^ 0x0001],bright);
  325.  
  326.       if(vc == 0)
  327.       {
  328.  
  329.           /* open this polygon */
  330. #ifdef DRAWDEBUG
  331.           printf("call areamove...\n");
  332. #endif
  333.           x = (((*nextp)->x)+(TMPWIDTH>>1));
  334.           y = (((*nextp)->y)+(TMPHEIGHT>>1));
  335.  
  336.           if (x<0) x = 0;
  337.           if (y<0) y = 0;
  338.           if (x>TMPWIDTH-1) x = TMPWIDTH-1;
  339.           if (y>TMPHEIGHT-1) y = TMPHEIGHT-1;
  340.  
  341.           x -= ( ( TMPWIDTH  - (window->RPort->BitMap->BytesPerRow<<3) ) >> 1 );
  342.           y -= ( ( TMPHEIGHT - (window->RPort->BitMap->Rows) ) >> 1 );
  343.  
  344.           firstx = x;
  345.           firsty = y;
  346.  
  347.           /* move into the raster that we're NOT subdisplaying */
  348.  
  349. #ifndef FIXEDILLUMINATION
  350.           if( (lastn != *nextn) && (endflag) )
  351.           {
  352.               AreaEnd(rp[frametoggle ^ 0x0001]);
  353.          endflag = FALSE;
  354.           }
  355. #endif
  356.  
  357.           AreaMove(rp[frametoggle ^ 0x0001],x,y);
  358.  
  359.       }
  360.       else
  361.       {
  362.  
  363.           /* continue this polygon */
  364. #ifdef DRAWDEBUG
  365.           printf("call areadraw...\n");
  366. #endif
  367.           x = (((*nextp)->x)+(TMPWIDTH>>1));
  368.           y = (((*nextp)->y)+(TMPHEIGHT>>1));
  369.  
  370.           if (x<0) x = 0;
  371.           if (y<0) y = 0;
  372.           if (x>TMPWIDTH-1) x = TMPWIDTH-1;
  373.           if (y>TMPHEIGHT-1) y = TMPHEIGHT-1;
  374.  
  375.           x -= ( ( TMPWIDTH  - (window->RPort->BitMap->BytesPerRow<<3) ) >> 1 );
  376.           y -= ( ( TMPHEIGHT - (window->RPort->BitMap->Rows) ) >> 1 );
  377.  
  378.           /* draw into the raster that we're NOT subdisplaying */
  379.  
  380.           AreaDraw(rp[frametoggle ^ 0x0001],x,y);
  381.  
  382.       }
  383.  
  384.       /* increment the nextp pointer */
  385.  
  386.       nextp++;
  387.  
  388.         }
  389.  
  390.        /* close this polygon */
  391.  
  392. #ifdef DRAWDEBUG
  393.        printf("call areaend...\n");
  394. #endif
  395.        /* end raster that we're NOT subdisplaying (or continue collecting polygons) */
  396.  
  397.        /* last polygon subdisplayed is this one */
  398.  
  399.        lastn = *nextn;
  400.  
  401. #ifndef FIXEDILLUMINATION
  402.        if(lastn  == *(nextn+1))
  403.        {
  404.       /* last polygon subdisplayed has same normal as next polygon to be subdisplayed */
  405.  
  406. #ifdef DRAWDEBUG
  407.       printf("last poly subdisplayed has same normal as next polygon to be subdisplayed...draw\n");
  408. #endif
  409.       /* draw, but do not terminate this polygon in this sequence */
  410.  
  411.       /* note : need graphics 28.5 or greater to do following trick ! */
  412.  
  413.       AreaDraw(rp[frametoggle ^ 0x0001],firstx,firsty);
  414.       endflag = TRUE;
  415.  
  416.       /* if graphics 28.4 or less  do this standard thing */
  417.  
  418.       /* AreaEnd(rp[frametoggle ^ 0x0001]); */
  419.       /* endflag = FALSE; */
  420.        }
  421.        else
  422.        {
  423.       /* last polygon subdisplayed has different normal from next polygon to be subdisplayed */
  424.  
  425. #ifdef DRAWDEBUG
  426.       printf("last poly subdisplayed has deffernt normal from next polygon to be subdisplayed...end\n");
  427. #endif
  428.       /* terminate this polygon sequence */
  429.  
  430.       AreaEnd(rp[frametoggle ^ 0x0001]);
  431.       endflag = FALSE;
  432.  
  433.        }
  434. #else
  435.        {
  436.       /* terminate this polygon sequence */
  437.  
  438.       AreaEnd(rp[frametoggle ^ 0x0001]);
  439.       endflag = FALSE;
  440.  
  441.        }
  442. #endif
  443.  
  444.        /* increment nextcolor, nextn pointers */
  445.  
  446.        nextcolor++;
  447.        nextn++;
  448.        
  449.    }
  450.  
  451.    if(endflag)
  452.    {
  453.        /* terminate series of "same normal" polygons after polyloop exit */
  454.  
  455. #ifdef DRAWDEBUG
  456.        printf("close last polygon in series...\n");
  457. #endif
  458.        AreaEnd(rp[frametoggle ^ 0x0001]);
  459.    }
  460.    
  461.     }
  462.  
  463.     thisobjectinfo = thisobjectinfo->nextobjectinfo;
  464.  
  465.     } /* end while (thisobject) */
  466.  
  467. }
  468.  
  469.  
  470.